# -*- coding: utf-8 -*-
"""
  @Time    : 2024/3/7 9:27
  @Author  : 
  @email   : 
  @File    : home.py
"""
from flask import Blueprint, render_template, send_from_directory, current_app, Response
from lib.docker_manage import DockerEngine
from lib.tools import check_endpoint_status, SerializeData
from extensions import registry, container_pids_limit, container_pids_usage
from prometheus_client import generate_latest
import concurrent.futures
import os

# 定义蓝图，路由分组
home_bp = Blueprint('home_bp', __name__, url_prefix='/')


obj = SerializeData(fp="config.json")
config = obj.load_file()
service_host = config['SERVICE_HOST']
base_url_list = config['BASE_URL_PROD']
base_url_list.extend(config['BASE_URL_TEST'])


def get_node_status():
    res_list = []
    filters = {}
    filters['status'] = "running"
    for base_url in base_url_list:
        endpoint = base_url.split('/')[2]
        endpoint_name = endpoint.split(':')[0]
        res_code = check_endpoint_status(endpoint=endpoint)
        tmp_dict = {}
        tmp_dict['endpoint_name'] = endpoint_name
        if res_code != 200:
            tmp_dict['endpoint_status'] = "disconnect"
            tmp_dict['container_num'] = "???"
        else:
            tmp_dict['endpoint_status'] = "online"
            docker_client = DockerEngine(base_url=base_url)
            tmp_dict['container_num'] = len(
                docker_client.container_info(filters=filters).keys())
        res_list.append(tmp_dict)
    return res_list


ROUTE_LIST = [
    {
        "type": "table",
        "title": "节点状态",
        "urls": get_node_status()
    },
    {
        "type": "link",
        "title": "容器信息",
        "urls": [
            "http://%s/containers/info/prod" % service_host,
            "http://%s/containers/info/test" % service_host,
            "http://%s/containers/info/prod/464_thirdstock" % service_host,
            "http://%s/containers/info/prod?cip=10.50.4.25" % service_host,
            "http://%s/containers/info/prod?status=running" % service_host,
            "http://%s/containers/info/prod/single" % service_host,
            "http://%s/containers/stats/prod/10.50.4.25" % service_host,
            "http://%s/containers/stats/test/10.50.0.25" % service_host
        ]
    },
    {
        "type": "link",
        "title": "容器监控",
        "urls": [
            "https://grafana-docker.sinajs.cn/",
        ]
    },
    {
        "type": "link",
        "title": "空间使用",
        "urls": [
            "http://%s/docker/system/df/hq-cntr-tel.sinajs.cn" % service_host,
            "http://%s/docker/system/df/hq-cntr-uni.sinajs.cn" % service_host,
            "http://%s/docker/system/df/hq-cntr-test.sinajs.cn" % service_host]
    },
    {
        "type": "link",
        "title": "调度任务",
        "urls": [
            "http://%s/scheduler" % service_host,
            "http://%s/tasks/list" % service_host, ]
    }
]


@home_bp.route('/', methods=['GET'])
def index():
    res_list = get_node_status()
    for i in range(len(ROUTE_LIST)):
        if ROUTE_LIST[i]['title'] == "节点状态":
            ROUTE_LIST[i]['urls'] = res_list
            break
    current_app.logger.info(f'access /index.html')
    return render_template('index.html', routes=ROUTE_LIST)


@home_bp.route('/favicon.ico')
def favicon():
    return send_from_directory(
        os.path.join(current_app.root_path, 'static'),
        'favicon.ico',
        mimetype='image/vnd.microsoft.icon')


def push_pids_to_prometheus(node_name, container_name, base_url):
    docker_client = DockerEngine(base_url=base_url)
    stats_info = docker_client.container_stats(container_name=container_name)
    pids_stats = dict(stats_info['pids_stats'])
    container_pids_usage.labels(
        node_name,
        container_name).set(
        pids_stats.get(
            'current',
            0))
    container_pids_limit.labels(
        node_name,
        container_name).set(
        pids_stats.get(
            'limit',
            float("inf")))


@home_bp.route('/metrics', methods=['GET'])
def metrics():
    """
    Prometheus Exporter
    :return:
    """
    if current_app.config.get('PROM_MAX_THREAD'):
        max_workers=current_app.config.get('PROM_MAX_THREAD')
    else:
        max_workers=50

    with open('/etc/hostname') as f:
        node_name = f.read().strip()
    # with open('hostname') as f:
    #     node_name = f.read().strip()
    base_url = "tcp://%s:2375" % node_name
    docker_client = DockerEngine(base_url=base_url)
    container_info = docker_client.container_info()
    # 多线程获取容器pids信息
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        for container_name in container_info.keys():
            executor.submit(
                push_pids_to_prometheus,
                node_name,
                container_name,
                base_url)

    return Response(generate_latest(registry), mimetype="text/plain")
